package com.rockcent.wechat.controller;

import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.mall.lib.domain.Customer;
import com.rockcent.mall.lib.domain.SMSEvent;
import com.rockcent.mall.lib.domain.enumclass.SMSEventType;
import com.rockcent.mall.lib.domain.enumclass.TerminalType;
import com.rockcent.mall.lib.dto.CustomerDto;
import com.rockcent.mall.lib.helper.BaseCaptchaHelper;
import com.rockcent.mall.lib.repository.CustomerRepository;
import com.rockcent.mall.lib.repository.SMSEventRepository;
import com.rockcent.wechat.Routes;
import com.rockcent.wechat.helper.CustomerHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.sql.Date;

/**
 * Created by oj on 2016/11/8 0008.
 * 发送验证码
 */
@RestController
@RequestMapping(value = Routes.API_PREFIX)
public class SMSController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(SMSController.class);
    @Autowired
    private CustomerRepository customerRepository;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SMSEventRepository smsEventRepository;
    @Autowired
    private CustomerHelper customerHelper;
    @Autowired
    private BaseCaptchaHelper baseCaptchaHelper;

    /**
     * @api {get} /api/v2/sms/send_valid_code 发送验证码短信
     * @apiGroup sms
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String} phoneNum 验证电话号码
     * @apiParam {String} fromTerminal 终端类型 WECHAT , IOS  , ANDROID , BROWER, MERCHANT,WXAPP
     *
     * @apiSuccessExample {json} Success-Response:
     * HTTP/1.1 200 OK
     *{
     *      "code": "1",
     *      "desc": "成功",
     *      "data": "发送成功"
     *}
     *
     */
    @RequestMapping(value = Routes.SEND_VALID_CODE, method = RequestMethod.GET)
    public JsonResult sendValidCode(String phoneNum, String fromTerminal, HttpServletRequest request) {
        CustomerDto customerDto = customerHelper.getSession(request);
        RestDoing doing = jr -> {
            //校验
            if (StringUtils.isBlank(phoneNum)) {
                jr.errorParam("phoneNum is null",log);
                return;
            }
            if (StringUtils.isBlank(fromTerminal)) {
                jr.errorParam("fromTerminal is null",log);
                return;
            }
//            Customer mobileCustomer = customerRepository.findByMobileAndMallId(phoneNum, customerDto.getMallId());
//            if (mobileCustomer != null){
//                jr.errorParam("该手机号已经被绑定过了");
//                return;
//            }
            Object oCaptcha = redisTemplate.opsForValue().get(customerDto.getId()+":"+phoneNum);
            if (oCaptcha != null){
                jr.data = "验证码已经发送，请注意查看";
                return;
            }
            //获取并发送验证码
            int timeLeft = 180;//验证码有效时间2min
            String captchaTemp = baseCaptchaHelper.send(phoneNum,customerDto.getMallName(),customerDto.getId()+":"+phoneNum ,timeLeft); //验证码captchaTemp

            String sendResult = "SMS send fail";
            boolean result = false;
            if (StringUtils.isNotBlank(captchaTemp)) {
                sendResult = "SMS send success";
                result = true;
            }
            if (!result) {
                jr.data = "发送失败，请稍后再试";
            }
            jr.data = "验证码已经发送，请注意查看";
            //记录发送事件
            SMSEvent smsEvent = new SMSEvent();
            smsEvent.setDateCreated(new Date(System.currentTimeMillis()));
            smsEvent.setEventType(SMSEventType.SendVerifyCodeSMS);
            TerminalType terminal = TerminalType.valueOf(fromTerminal.trim());
            smsEvent.setFromTerminal(terminal);
            smsEvent.setMallName(customerDto.getMallId().toString());
            //String sendResult = captchaTemp.? "SMS send success" : "SMS send fail";

            smsEvent.setKeyInfo(phoneNum + sendResult);
            smsEvent.setTriggerMan(phoneNum);
            smsEvent.setExecuteResult(result);
            smsEventRepository.save(smsEvent);

        };
        return doing.go(request, log);
    }


    /**
     * @api {get} /api/v2/sms/send_phone_valid_code 发送手机验证码短信
     * @apiGroup sms
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String} phoneNum 验证电话号码
     * @apiParam {String} fromTerminal 终端类型 WECHAT , IOS  , ANDROID , BROWER, MERCHANT,WXAPP
     *
     * @apiSuccessExample {json} Success-Response:
     * HTTP/1.1 200 OK
     *{
     *      "code": "1",
     *      "desc": "成功",
     *      "data": "发送成功"
     *}
     *
     */
    @RequestMapping(value = Routes.SEND_PHONE_VALID_CODE, method = RequestMethod.GET)
    public JsonResult sendPhoneValidCode(String phoneNum, String fromTerminal, HttpServletRequest request) {
        CustomerDto customerDto = customerHelper.getSession(request);
        RestDoing doing = jr -> {
            //校验
            if (StringUtils.isBlank(phoneNum)) {
                jr.errorParam("phoneNum is null",log);
                return;
            }
            if (StringUtils.isBlank(fromTerminal)) {
                jr.errorParam("fromTerminal is null",log);
                return;
            }

            Object oCaptcha = redisTemplate.opsForValue().get(customerDto.getId()+":"+phoneNum);
            if (oCaptcha != null){
                jr.data = "验证码已经发送，请注意查看";
                return;
            }
            //获取并发送验证码
            int timeLeft = 180;//验证码有效时间3min
            String captchaTemp = baseCaptchaHelper.send(phoneNum,customerDto.getMallName(),customerDto.getId()+":"+phoneNum ,timeLeft); //验证码captchaTemp

            String sendResult = "SMS send fail";
            boolean result = false;
            if (StringUtils.isNotBlank(captchaTemp)) {
                sendResult = "SMS send success";
                result = true;
            }
            if (!result) {
                jr.data = "发送失败，请稍后再试";
            }
            jr.data = "验证码已经发送，请注意查看";
            //记录发送事件
            SMSEvent smsEvent = new SMSEvent();
            smsEvent.setDateCreated(new Date(System.currentTimeMillis()));
            smsEvent.setEventType(SMSEventType.SendVerifyCodeSMS);
            TerminalType terminal = TerminalType.valueOf(fromTerminal.trim());
            smsEvent.setFromTerminal(terminal);
            smsEvent.setMallName(customerDto.getMallId().toString());
            //String sendResult = captchaTemp.? "SMS send success" : "SMS send fail";

            smsEvent.setKeyInfo(phoneNum + sendResult);
            smsEvent.setTriggerMan(phoneNum);
            smsEvent.setExecuteResult(result);
            smsEventRepository.save(smsEvent);

        };
        return doing.go(request, log);
    }


    /**
     * @api {get} /api/v2/sms/validate_code 验证码校验
     * @apiGroup sms
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String} phoneNum 验证电话号码
     * @apiParam {String} captchaTemp 客户手机收到验证码
     * @apiParam {boolean} protocol 协议签订
     *
     * @apiSuccessExample {json} Success-Response:
     * HTTP/1.1 200 OK
     *{
     *   "code": "1",
     *   "desc": "成功",
     *   "data": false
     *}
     *
     */
    @RequestMapping(value = Routes.VALIDATE_CODE, method = RequestMethod.GET)
    public JsonResult validateCode(String phoneNum, String captchaTemp, boolean protocol, HttpServletRequest request) {
        CustomerDto customerDto = customerHelper.getSession(request);
        RestDoing doing = jr -> {
            Customer customer = customerRepository.findOne(customerDto.getId());
            if (StringUtils.isNotBlank(customer.getMobile())){
                jr.errorParam("该账户已经绑定过手机号",log);
                return;
            }
            if (StringUtils.isBlank(phoneNum)) {
                jr.errorParam("phoneNum is null",log);
                return;
            }
            if (StringUtils.isBlank(captchaTemp)) {
                jr.errorParam("captchaTemp is null",log);
                return;
            }
            if (protocol == false) {
                jr.errorParam("protocol can not false",log);
                return;
            }
//            Customer mobileCustomer = customerRepository.findByMobileAndMallId(phoneNum, customerDto.getMallId());
            /*if (mobileCustomer != null){
                jr.errorParam("该手机号已经被绑定过了");
                return;
            }*/
            //验证码的校验
            boolean result = false;
            Object oCaptcha = redisTemplate.opsForValue().get(customerDto.getId()+":"+phoneNum);
            if (null != oCaptcha && String.valueOf(oCaptcha).equals(captchaTemp)) {
                result = true;
                customer.setMobile(phoneNum);
                customer.setProtocol(Whether.YES);
                //每个验证码只能用一次
                redisTemplate.delete(customerDto.getId()+":"+phoneNum);
                customerRepository.save(customer);
            }
            jr.setData(result);
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /api/v2/sms/validate_phone_code 手机号码校验
     * @apiGroup sms
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String} phoneNum 验证电话号码
     * @apiParam {String} captchaTemp 客户手机收到验证码
     *
     * @apiSuccessExample {json} Success-Response:
     * HTTP/1.1 200 OK
     *{
     *   "code": "1",
     *   "desc": "成功",
     *   "data": false
     *}
     *
     */
    @RequestMapping(value = Routes.VALIDATE_PHONE_CODE, method = RequestMethod.GET)
    public JsonResult validatePhoneCode(String phoneNum, String captchaTemp, HttpServletRequest request){
        CustomerDto customerDto = customerHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (StringUtils.isBlank(phoneNum)) {
                jsonResult.errorParam("phoneNum is null",log);
                return;
            }
            if (StringUtils.isBlank(captchaTemp)) {
                jsonResult.errorParam("captchaTemp is null",log);
                return;
            }
            boolean result = false;
            Object oCaptcha = redisTemplate.opsForValue().get(customerDto.getId()+":"+phoneNum);
            if (null != oCaptcha && String.valueOf(oCaptcha).equals(captchaTemp)) {
                result = true;
                redisTemplate.delete(customerDto.getId()+":"+phoneNum);
            }
            jsonResult.setData(result);
        };
        return doing.go(request, log);
    }
}
